--Really old blaze code ported from (early) 2.1. Over 10 years old and we're still using it for some reason.
freeslot("SPR_BLFR", "sfx_blzjmp", "MT_BLAZEHITBOX", "sfx_blzhvr", "sfx_blzrev")


mobjinfo[MT_BLAZEHITBOX] = {
  spawnstate = S_INVISIBLE,
  speed = 6,
  radius = 64*FRACUNIT,
  height = 60*FRACUNIT,
  flags = MF_NOGRAVITY|MF_NOCLIPHEIGHT,
}

sfxinfo[sfx_blzjmp].caption = "Tornado fire"
sfxinfo[sfx_blzhvr].caption = "Hover"
sfxinfo[sfx_blzrev].caption = "Burst dash"

//Lerp function.
local function Lerp(min, max, fac)
	return (min + FixedMul(fac, (max - min)))
end

local function set_add(mo) mo.blendmode = AST_ADD end

local preent = 5
addHook("ThinkFrame", do
	for player in players.iterate
		if not player.mo or player.mo.skin != "blaze" then continue end
		if P_PlayerInPain(player) return end
		local mo = player.mo		-- im lazy what can i say
	
		-- HANDLE HOVER
		
		if mo.blazejumpt == nil
			mo.blazejumpt = 0
		end

		if player.cmd.buttons & BT_JUMP
			mo.blazejumpt = $1+1
				
			if mo.blazejumpt == 1
				mo.blazejump = true
			else
				mo.blazejump = false
			end
		else
			mo.blazejumpt = 0
			mo.blazejump = false
		end


		if (player.cmd.buttons & BT_SPIN)
			mo.holdspin = true
		else
			mo.holdspin = false
		end
		

		/*if mo.blazejump
		and mo.blazejumping > 3	-- don' trigger on first jump frame
		and not (player.powers[pw_carry])
			if not mo.hoverinjump	-- bad
				mo.hovertimer = 125
			end
			mo.hoverinjump = true
			S_StartSound(player.mo, sfx_blzhvr)
			mo.momz = 0
		end
		
		if P_IsObjectOnGround(mo)
			mo.hoverinjump = nil
			mo.hovertimer = 0
		end
		
		if (player.powers[pw_carry])
			mo.hoverinjump = nil
			mo.hovertimer = 0
		end

		if mo.hovertimer
		and mo.hoverinjump
		and not P_IsObjectOnGround(mo)
		and not (player.powers[pw_carry])
			
			if player.cmd.buttons & BT_JUMP

				mo.blazejumping = false
				mo.hovertimer = $1-1
				P_SetObjectMomZ(player.mo, FixedMul(mo.scale, Lerp(-3*FRACUNIT, 0, FixedDiv(mo.hovertimer*FRACUNIT, 105*FRACUNIT))), false)
				player.pflags = $1 & !PF_JUMPED
				player.mo.state = S_PLAY_FALL
		
				local limit = 6*FRACUNIT
				local hypot = FixedHypot(player.mo.momx, player.mo.momy)
		
				if hypot > limit
					--local slope = FixedMul(mo.scale, FixedDiv(player.mo.momy, player.mo.momx))
					local ratio = FixedMul(mo.scale, FixedDiv(hypot, limit))
				end
				if not (player.flame1 and player.flame1.valid) and not (player.flame2 and player.flame2.valid)--leveltime % 7 == 0
					local flame1 = P_SpawnMobjFromMobj(player.mo, P_ReturnThrustX(flame1, player.drawangle+FixedAngle(180*FRACUNIT), 7*FRACUNIT)+
					P_ReturnThrustX(flame1, player.drawangle+FixedAngle(90*FRACUNIT), 5*FRACUNIT), 
					P_ReturnThrustY(flame1, player.drawangle+FixedAngle(180*FRACUNIT), 7*FRACUNIT)+
					P_ReturnThrustX(flame1, player.drawangle+FixedAngle(90*FRACUNIT), 5*FRACUNIT), 
					-20*FRACUNIT*P_MobjFlip(player.mo), MT_BLAZE_HOVERFIRE)
					flame1.invuln = 7
					flame1.target = player.mo
					flame1.flame1 = true
					flame1.scale = player.mo.scale --+ player.mo.scale/4
					player.flame1 = flame1
					local flame2 = P_SpawnMobjFromMobj(player.mo, P_ReturnThrustX(flame2, player.drawangle+FixedAngle(180*FRACUNIT), 7*FRACUNIT)+
					P_ReturnThrustX(flame1, player.drawangle+FixedAngle(-90*FRACUNIT), 5*FRACUNIT),
					P_ReturnThrustY(flame2, player.drawangle+FixedAngle(180*FRACUNIT), 7*FRACUNIT)+
					P_ReturnThrustY(flame1, player.drawangle+FixedAngle(-90*FRACUNIT), 5*FRACUNIT), 
					-20*FRACUNIT*P_MobjFlip(player.mo), MT_BLAZE_HOVERFIRE)
					flame2.invuln = 7
					flame2.target = player.mo
					flame2.flame2 = true
					flame2.scale = player.mo.scale --+ player.mo.scale/4
					player.flame2 = flame2
				end
			end
		end*/
		
		
		-- HOVER END

		if mo.spintimer == 0
		or mo.spintimer == nil
			player.charability = CA_NONE
		end	
		
		if mo.spintimer == nil or P_PlayerInPain(player) or player.mo.health == 0
			mo.spintimer = 0
		elseif mo.spintimer > 0
			mo.spintimer = $1-1
		end
		
		/*if mo.hovertimer == nil or P_IsObjectOnGround(player.mo)
			mo.hovertimer = 125
		elseif mo.hovertimer > 0 and mo.hovertimer < 105 and not (player.cmd.buttons & BT_SPIN) and not P_IsObjectOnGround(player.mo)
			mo.hovertimer = 0
		end*/
		
		if mo.spintimer and mo.spintimer > 0
			player.charflags = $1|SF_RUNONWATER
			/*if mo.spintimer == 1
				player.mo.sprite = states[player.mo.state].sprite
				player.mo.frame = states[player.mo.state].frame
			end*/
			
			if P_IsObjectOnGround(player.mo) and not (player.mo.eflags & MFE_UNDERWATER)
				player.mo.friction = FRACUNIT
				player.acceleration = 20
				
				local flame = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_SPINFIRE)
				flame.scale = mo.scale/4
				flame.destscale = 2*mo.scale
				flame.target = player.mo
				flame.fuse = TICRATE/2
			end
		else
			player.charflags = $1 & !SF_RUNONWATER
			player.acceleration = 41
		end
		
		if not mo.blazefires
			mo.blazefires = {}
		end
		
		if mo.blazejumping or mo.spintimer > 1 --or player.mo.state == S_PLAY_ROLL
		--or player.pflags & PF_SPINNING and not (player.pflags & (PF_STARTDASH | PF_JUMPED))

			-- blaze tornado fire

			if mo.spintimer > 1
			--or mo.hovertimer > 1
			--and player.cmd.buttons & BT_JUMP
					
				local angle = P_RandomRange(1, 359)*ANG1
					
				local x = mo.x + 64*(cos(angle))
				local y = mo.y + 64*(sin(angle))
				local item = P_SpawnMobjFromMobj(player.mo, 0, 0, 0+P_RandomRange(0, mo.height/FRACUNIT)*FRACUNIT, MT_PARTICLE)
				item.angle = angle
				if not (mo.eflags & MFE_UNDERWATER)
					item.sprite = SPR_DFLM
					item.frame = F|FF_FULLBRIGHT|TR_TRANS50
					item.fuse = 10
				else
					item.sprite = SPR_BUBP
					item.momz = FRACUNIT*3
					item.fuse = 30
				end
				item.target = mo
				item.atdist = (24*mo.scale)/FRACUNIT
				item.scale = mo.scale/3
				//item.momz = mo.scale/4
				table.insert(mo.blazefires, item)
				
			end

			for k,v in ipairs(mo.blazefires)
				if v and v.valid
						
					v.angle = $-ANG1*24
					v.atdist = $+(mo.scale)/FRACUNIT
					v.scale = $+mo.scale/64
					v.momz = mo.momz

					local target_x = mo.x + v.atdist*(cos(v.angle))
					local target_y = mo.y + v.atdist*(sin(v.angle))
						
					P_InstaThrust(v, R_PointToAngle2(v.x, v.y, target_x, target_y), FRACUNIT*2)
					P_TeleportMove(v, target_x, target_y, v.z)
				end
			end

			--player.mo.sprite2 = SPR2_FIRE
			--player.mo.frame = (leveltime/2) % 4
			
			local spawndir = (leveltime % 17) * ANG20
			local xdist = FixedMul(FRACUNIT, FixedMul(21*FRACUNIT, cos(spawndir)))
			local ydist = FixedMul(FRACUNIT, FixedMul(21*FRACUNIT, sin(spawndir)))
			if not (player.mo.eflags & MFE_UNDERWATER)
				local flame1 = P_SpawnMobjFromMobj(player.mo, 0+xdist,0+ydist, 0+(20*FRACUNIT), MT_BLAZE_JUMPFIRE)
				local flame2 = P_SpawnMobjFromMobj(player.mo, 0-xdist, 0-ydist, 0+(20*FRACUNIT), MT_BLAZE_JUMPFIRE)
				set_add(flame1)
				set_add(flame2)			
			
				--flame1.sprite = SPR_DFLM
				--flame1.frame = F|FF_FULLBRIGHT|TR_TRANS70
				flame1.fuse = 12
				flame1.scale = mo.scale-mo.scale/2
				flame1.destscale = 50*mo.scale
				flame1.scalespeed = mo.scale/8
				flame1.target = mo
				flame1.color = player.blazeflamecolor
				--flame2.sprite = SPR_DFLM
				--flame2.frame = F|FF_FULLBRIGHT|TR_TRANS70
				flame2.fuse = 12
				flame2.scale = mo.scale-mo.scale/2
				flame2.destscale = 50*mo.scale
				flame2.scalespeed = mo.scale/8
				flame2.target = mo
				flame2.color = player.blazeflamecolor
			else
				local flame1 = P_SpawnMobjFromMobj(player.mo, 0+xdist,0+ydist, 0+(20*mo.scale), MT_PARTICLE)
				local flame2 = P_SpawnMobjFromMobj(player.mo, 0-xdist, 0-ydist, 0+(20*mo.scale), MT_PARTICLE)
				flame1.tics = 35
				--flame1.fuse = 6
				flame1.scale = 1
				flame1.destscale = mo.scale*5
				flame1.scalespeed = mo.scale/12
				flame1.momz = FixedMul(mo.scale, 2*FRACUNIT)
				
				flame2.tics = 35
				--flame2.fuse = 6
				flame2.scale = 1
				flame2.destscale = mo.scale*5
				flame2.scalespeed = mo.scale/12
				flame2.momz = FixedMul(mo.scale, 2*FRACUNIT)
			
			end
			
			local ghost = P_SpawnGhostMobj(player.mo)
			ghost.fuse = 3
			if ghost.tracer and ghost.tracer.valid
				ghost.tracer.fuse = 3
			end
		else
			if mo.blazefires
				mo.blazefires = {}
			end
		end
	end
	// katsy note: i moved this here to prevent creating an extra thinkframe hook for no reason
	if not preent return end
	preent = $-1
	if preent return end
	print("\x89\RushChars \x80\- \x88\Sprites by Inazuma, Lightdasher, and Burning Loaf.", "\x87\Code by Frostiikin, katsy, SMS Alfredo, Lach, Krabs, Jay and Snu.")
end)

addHook("MobjThinker", function(mo)
	if mo and mo.valid and mo.health and mo.target and mo.target.valid and mo.target.health
		if mo.fuse > 7
			mo.momx = mo.target.momx
			mo.momy = mo.target.momy
		else
			mo.momx = 0
			mo.momy = 0
		end
	end
end, MT_BLAZE_JUMPFIRE)

addHook("JumpSpecial", function(player)
	if player.mo and player.mo.skin == "blaze"
		player.mo.spintimer = 0
	end
end)

addHook("MobjThinker", function(dust)
	if not (dust and dust.valid and dust.target   ) return end
	local pmo = dust.target
	if (pmo and pmo.valid and pmo.skin == "blaze")
		if not (pmo.eflags & MFE_UNDERWATER)
			P_RemoveMobj(dust)
		--elseif (dust.state >= S_SPINDUST1 and dust.state <= S_SPINDUST4)
			--dust.state = S_BUBBLES1
		end
	end
end, MT_SPINDUST)

addHook("MobjDamage", function(mobj, inflictor, source)
	if inflictor and ((inflictor.flags & MF_ENEMY) or (inflictor.flags & MF_BOSS)) and (mobj.spintimer or mobj.blazejumping)
		P_DamageMobj(inflictor, mobj, mobj, 1)
		if (inflictor.flags & MF_BOSS)
			mobj.momx = -mobj.momx
			mobj.momy = -mobj.momy
		end
		mobj.momz = abs(mobj.momz)
		
		return true
	end
end, MT_PLAYER)

addHook("MobjMoveCollide", function(mobj, othermobj)
	if (mobj.spintimer) and (mobj.spintimer > 0) and (othermobj.flags & MF_MONITOR) and mobj.z >= othermobj.z-mobj.height and mobj.z <= othermobj.z+othermobj.height+2*FRACUNIT
		P_KillMobj(othermobj, mobj, mobj)
		mobj.momz = abs(mobj.momz)
	end
	if mobj.player and (mobj.skin == "blaze") and mobj.player.blazeboosting and (othermobj.type == MT_SPIKE or othermobj.type == MT_WALLSPIKE)
	and (abs(mobj.z - othermobj.z) <= FixedMul(60<<FRACBITS, othermobj.scale))
		if mobj.z >= othermobj.z-othermobj.height and mobj.z <= othermobj.z+othermobj.height+othermobj.height
			P_KillMobj(othermobj, mobj)
			return false
		end
	end
end, MT_PLAYER)

/*addHook("ShouldDamage", function(mo, inflictor)

	if not mo.player return end
	if not mo.skin == "blaze" return end
	
	if inflictor and inflictor.valid and inflictor.flags & MF_FIRE then return false end
	if not inflictor and P_PlayerTouchingSectorSpecial(mo.player, 1, 3) return false end

end, MT_PLAYER)*/
